package cn.lix.sc.rpc.impl.common.utils;

import cn.lix.sc.rpc.impl.common.annotations.RpcService;
import cn.lix.sc.rpc.impl.common.dto.EnhancedRpcRequest;
import cn.lix.sc.rpc.impl.common.exception.SystemException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 增强的参数转换器，支持文件流和多种内容类型
 *
 * @author lix
 * @date 2024
 */
public class EnhancedParametersConverter {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 根据请求类型转换参数
     */
    public static Object[] convert(EnhancedRpcRequest request, Class[] types) throws Exception {
        if (types == null || types.length < 1) {
            return new Object[0];
        }

        switch (request.getContentType()) {
            case JSON:
                return convertJsonParameters(request.getParameters(), types);
            case MULTIPART:
                return convertMultipartParameters(request, types);
            case OCTET_STREAM:
                return convertStreamParameters(request, types);
            case TEXT_PLAIN:
                return convertTextParameters(request.getParameters(), types);
            default:
                return convertJsonParameters(request.getParameters(), types);
        }
    }

    /**
     * JSON参数转换（原有逻辑）
     */
    private static Object[] convertJsonParameters(String param, Class[] types) throws Exception {
        if (StringUtils.isEmpty(param) || types.length < 1) {
            return new Object[0];
        }

        Object[] parameters = new Object[types.length];
        JsonNode array = objectMapper.readTree(param);

        if (!array.isArray() || array.size() != types.length) {
            throw SystemException.error("方法参数不一致");
        }

        for (int i = 0; i < types.length; i++) {
            parameters[i] = convertJsonParameter(array, i, types[i]);
        }
        return parameters;
    }

    /**
     * 单个JSON参数转换
     */
    private static Object convertJsonParameter(JsonNode array, int index, Class<?> type) {
        JsonNode node = array.get(index);
        if (node == null || node.isNull()) {
            return null;
        }

        if (type == String.class) {
            return node.asText();
        } else if (type == Date.class) {
            return new Date(node.asLong());
        } else if (type == Byte.class || type == byte.class) {
            return (byte) node.asInt();
        } else if (type == Short.class || type == short.class) {
            return (short) node.asInt();
        } else if (type == Integer.class || type == int.class) {
            return node.asInt();
        } else if (type == Long.class || type == long.class) {
            return node.asLong();
        } else if (type == Double.class || type == double.class) {
            return node.asDouble();
        } else if (type == Float.class || type == float.class) {
            return (float) node.asDouble();
        } else if (type == Boolean.class || type == boolean.class) {
            return node.asBoolean();
        } else {
            return objectMapper.convertValue(node, type);
        }
    }

    /**
     * Multipart参数转换（文件上传）
     */
    private static Object[] convertMultipartParameters(EnhancedRpcRequest request, Class[] types) throws Exception {
        Object[] parameters = new Object[types.length];

        // 查找MultipartFile参数
        int fileParamIndex = -1;
        for (int i = 0; i < types.length; i++) {
            if (MultipartFile.class.isAssignableFrom(types[i])) {
                fileParamIndex = i;
                break;
            }
        }

        if (fileParamIndex >= 0 && request.getFileData() != null) {
            // 创建MockMultipartFile
            MultipartFile file = new SimpleMultipartFile(
                    request.getFileName(),
                    request.getOriginalFileName(),
                    request.getFileContentType(),
                    request.getFileData()
            );
            parameters[fileParamIndex] = file;
        }

        // 处理其他JSON参数
        if (!StringUtils.isEmpty(request.getParameters())) {
            JsonNode array = objectMapper.readTree(request.getParameters());
            if (array.isArray()) {
                for (int i = 0; i < types.length; i++) {
                    if (i != fileParamIndex && i < array.size()) {
                        parameters[i] = convertJsonParameter(array, i, types[i]);
                    }
                }
            }
        }

        return parameters;
    }

    /**
     * 流参数转换
     */
    private static Object[] convertStreamParameters(EnhancedRpcRequest request, Class[] types) throws Exception {
        Object[] parameters = new Object[types.length];

        // 查找InputStream参数
        int streamParamIndex = -1;
        for (int i = 0; i < types.length; i++) {
            if (InputStream.class.isAssignableFrom(types[i])) {
                streamParamIndex = i;
                break;
            } else if (types[i] == byte[].class) {
                streamParamIndex = i;
                break;
            }
        }

        if (streamParamIndex >= 0 && request.getFileData() != null) {
            if (InputStream.class.isAssignableFrom(types[streamParamIndex])) {
                parameters[streamParamIndex] = new ByteArrayInputStream(request.getFileData());
            } else if (types[streamParamIndex] == byte[].class) {
                parameters[streamParamIndex] = request.getFileData();
            }
        }

        // 处理其他参数
        if (!StringUtils.isEmpty(request.getParameters())) {
            JsonNode array = objectMapper.readTree(request.getParameters());
            if (array.isArray()) {
                for (int i = 0; i < types.length; i++) {
                    if (i != streamParamIndex && i < array.size()) {
                        parameters[i] = convertJsonParameter(array, i, types[i]);
                    }
                }
            }
        }

        return parameters;
    }

    /**
     * 纯文本参数转换
     */
    private static Object[] convertTextParameters(String param, Class[] types) throws Exception {
        if (types.length == 1 && types[0] == String.class) {
            return new Object[]{param};
        }
        // 对于多参数，尝试按分隔符拆分
        return convertJsonParameters(param, types);
    }

    /**
     * 检查方法是否支持指定的内容类型
     */
    public static boolean supportsContentType(Method method, RpcService.ContentType contentType) {
        Class<?>[] paramTypes = method.getParameterTypes();

        switch (contentType) {
            case MULTIPART:
                // 检查是否有MultipartFile参数
                for (Class<?> type : paramTypes) {
                    if (MultipartFile.class.isAssignableFrom(type)) {
                        return true;
                    }
                }
                return false;
            case OCTET_STREAM:
                // 检查是否有InputStream或byte[]参数
                for (Class<?> type : paramTypes) {
                    if (InputStream.class.isAssignableFrom(type) || type == byte[].class) {
                        return true;
                    }
                }
                return false;
            default:
                return true; // JSON和TEXT_PLAIN默认支持
        }
    }

    /**
     * 检查返回值是否为文件类型
     */
    public static boolean isFileReturnType(Class<?> returnType) {
        return InputStream.class.isAssignableFrom(returnType)
                || returnType == byte[].class
                || MultipartFile.class.isAssignableFrom(returnType);
    }

    /**
     * 生成增强的方法键，包含内容类型信息
     */
    public static String getEnhancedMethodKey(String className, Method method, RpcService.ContentType contentType) {
        String baseKey = MethodParametersJsonConvertor.getMethodKey(className, method);
        return baseKey + "_" + contentType.name();
    }
} 